package com.hsylient.remote.call.builder;

import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import okhttp3.Protocol;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.jackson.JacksonConverterFactory;

import java.util.Collections;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

/**
 * 通过OkHttpClient同步执行api请求RPC方法
 *
 * @author zhenghao
 * @date 2021/8/3 15:49
 */
@Slf4j
public class Generator {
    private static final OkHttpClient.Builder httpClient = new OkHttpClient.Builder()
            .connectTimeout(10, TimeUnit.SECONDS) // 连接超时10s
            .readTimeout(300, TimeUnit.SECONDS) // 读取超时300s
            .writeTimeout(60, TimeUnit.SECONDS); // 写入超时60s
    private static final Retrofit.Builder builder = new Retrofit.Builder()
            .addConverterFactory(JacksonConverterFactory.create())
            .client(httpClient.protocols(Collections.singletonList(Protocol.HTTP_1_1)).build());

    /**
     * 创建api
     *
     * @param apiClass apiClass
     * @param baseUrl  url
     * @return api
     */
    public synchronized static <S> S createApi(Class<S> apiClass, String baseUrl) {
        return builder.baseUrl(baseUrl)
                .build() // 构建retrofit
                .create(apiClass); // 构建api接口
    }

    /**
     * 创建api
     *
     * @param apiClass apiClass
     * @param baseUrl  url
     * @return api
     */
    public synchronized static <S> S createApi(Class<S> apiClass, String baseUrl, Long readTimeout) {
        if (readTimeout == null) return createApi(apiClass, baseUrl);
        return builder.client(
                new OkHttpClient.Builder()
                        .connectTimeout(10, TimeUnit.SECONDS) // 连接超时10s
                        .readTimeout(readTimeout, TimeUnit.SECONDS) // 读取超时60s
                        .writeTimeout(60, TimeUnit.SECONDS) // 写入超时60s
                        .protocols(Collections.singletonList(Protocol.HTTP_1_1)).build())
                .baseUrl(baseUrl)
                .build() // 构建retrofit
                .create(apiClass); // 构建api接口
    }

    // 解析异常相应信息
    private static <T> String getErrorMessage(ResponseBody responseBody, Response<T> res) {
        try {
            String errMsg = responseBody.string();
            // 完善报错信息
            if (StrUtil.isBlank(errMsg)) {
                errMsg = Optional.ofNullable(res.raw()).map(okhttp3.Response::message).orElse(res.message());
            }
            return errMsg;
        } catch (Exception e) {
            log.warn("[解析钱包请求异常响应异常] ..", e);
            return e.toString();
        }
    }
}
